package com.hgd.evp.common.utils;

import com.hgd.evp.common.ctree.TreeNode;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class TreeUtil<T extends TreeNode<T>> {

    /**
     * 构建树状结构数据
     *
     * @param treeNodes   树状结构里的节点
     * @param root        顶级节点的父节点，用于标识是否继续向上查找父节点
     * @param comparator  用于排序节点的比较器
     * @param clearOrigin 生成树状结构后是否删除数据源，当树状结构已生成的时候，源数据似乎已没有用处
     * @param <T>         树状节点泛型
     * @return 一个树状结构
     */
    public static <T extends TreeNode<T>> List<T> buildTree(List<T> treeNodes, Object root, Comparator<T> comparator, boolean clearOrigin) {
        List<T> trees = new ArrayList<>();

        for (T treeNode : treeNodes) {
            if (StringUtil.equals(String.valueOf(treeNode.getParentId()),
                    String.valueOf(root))) {
                trees.add(treeNode);
            }

            for (T treeNode02 : treeNodes) {
                if (StringUtil.equals(String.valueOf(treeNode02.getParentId()),
                        String.valueOf(treeNode.getId()))) {
                    // 说明treeNode02是treeNode的子节点
                    treeNode.getChileren().add(treeNode02);
                }
            }

            if (comparator != null && EmptyUtil.isNotEmpty(treeNode.getChileren())) {
                treeNode.getChileren().sort(comparator);
            }
        }

        if (comparator != null && EmptyUtil.isNotEmpty(trees)) {
            trees.sort(comparator);
        }

        if (clearOrigin) treeNodes.clear();

        return trees;
    }

    /**
     * 构建树状结构数据
     * 生成树状结构后，源数据将被删除掉
     *
     * @param treeNodes 树状结构里的节点
     * @param root      顶级节点的父节点，用于标识是否继续向上查找父节点
     * @param <T>       树状节点泛型
     * @return 一个树状结构
     */
    public static <T extends TreeNode<T>> List<T> buildTree(List<T> treeNodes, Object root) {
        return buildTree(treeNodes, root, true);
    }

    /**
     * 构建树状结构数据
     * 生成树状结构后，源数据将被删除掉
     *
     * @param treeNodes   树状结构里的节点
     * @param root        顶级节点的父节点，用于标识是否继续向上查找父节点
     * @param clearOrigin 生成树状结构后是否删除数据源，当树状结构已生成的时候，源数据似乎已没有用处
     * @param <T>         树状节点泛型
     * @return 一个树状结构
     */
    public static <T extends TreeNode<T>> List<T> buildTree(List<T> treeNodes, Object root, boolean clearOrigin) {
        return buildTree(treeNodes, root, null, clearOrigin);
    }
}
